home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 1 / LSD Compendium Deluxe 1.iso / a / programming / assembly / lsd-lo.s.lha / MultiDiskFileLoader.Src < prev    next >
Encoding:
Text File  |  1980-01-18  |  16.8 KB  |  851 lines

  1.  
  2. * EXAMPLE OF USE!
  3.  
  4.     
  5.     move.w #$4000,$dff09a    
  6.  
  7.     jsr INIT_DISK
  8.  
  9.     move.l #loadspace,a5    ;address of load
  10.     move.l #filename,a6        ;address of filename
  11.     moveq #0,d7        ;load mode set
  12.  
  13.     jsr LOAD_FILE
  14.  
  15.     tst.w d7            ;check for failure
  16.     beq.s loadok
  17.  
  18.     move.w #$7fff,d0        ;red screen = error
  19. erlp    move.w #$f00,$dff180
  20.     dbf d0,erlp
  21.  
  22. loadok    jsr MOTOR_OFF
  23.     move.w #$c000,$dff09a
  24.     rts
  25.  
  26. filename    dc.b "df0:testfile",$00
  27.  
  28.     even
  29.  
  30. loadspace dcb.l $8000,$00
  31.  
  32. *****************************************************************************
  33.  
  34.   *   System Independant Multi-Disk AmigaDos File Loader V1.1- 26/4/94   *
  35.   *----------------------------------------------------------------------*
  36.  
  37.                     * By PHIL RUSTON AKA:PHIL!94/LSD *
  38.  
  39. * You MUST Call "INIT_DISK" before loading for the 1st time ever!
  40.  
  41. * To LOAD A FILE Set:-
  42.  
  43. * A6 = Address of 0 ended filename (MUST include a path, subdirs allowed.)
  44. * A5 = Load address.
  45. * D7 = Mode: 0 = Load, 1 = Search and Return file length in A5 only.
  46.  
  47. * Then call: "LOAD_FILE" - All registers preserved except A5 and D7.
  48.  
  49. * A5 returns as last byte address of file + 1
  50. * D7 returns as 0 if load OK. Or one of the following errors:
  51.  
  52. * 01 = No speed signal from motor      (disk removed whilst loading?)
  53. * 02 = No DMA transfer time out        (not a dos disk / ''       '')
  54. * 03 = Disk removed from drive         (disk removed whilst loading)
  55. * 04 = Can't find that disk block      (disk corrupt)
  56. * 05 = Wrong track marker ID           ('')
  57. * 06 = Checksum error on disk block    ('')
  58. * 07 = Block requested out of range    ('')
  59. * 08 = Not a file                      (Its a directory!)
  60. * 09 = File not found                  
  61. * 0a = That drive is not connected.    (Direct drive access failed)
  62. * 0b = There is no disk in that drive. ( ''                    '' )
  63. * 0c = Disk requester.                 (Disk specified not in any drive)
  64. * 0d = No path given                   (I require disk or drive name!)
  65.  
  66. * Dont forget to call "MOTOR_OFF" when finished loading for a while!!
  67. * But NOT between each in batch of files!
  68.  
  69. * See DOCS for more info - If you use this code please credit me and
  70. * consider sendimg me a token of your appreciation.. Cash welcome!
  71.  
  72. *******************************************************************************
  73.  
  74.     section loadcode,code
  75.  
  76. **************
  77. * Initialize *
  78. **************
  79.  
  80. INIT_DISK    movem.l a0-a6/d0-d7,-(a7)
  81.     move.l #$dff000,a0
  82.     move.l #$bfd000,a1        
  83.     move.l #Variables,a2
  84.     clr.l attempts(a2)
  85.     clr.l tracksides(a2)
  86.     clr.l track_in(a2)
  87.     clr.l load_address(a2)
  88.     bsr Motor_off
  89.  
  90.     bset #3,drives_avail(a2)    ;df0: assumed always available
  91.     moveq #4,d1
  92. ID_drives    move.b #$7f,$100(a1)    ;what externals are connected?
  93.     bclr d1,$100(a1)        
  94.     move.w #100,d7
  95.     bsr cia_wait
  96.     move.b #$ff,$100(a1)        
  97.     bclr d1,$100(a1)
  98.     moveq #$1f,d7
  99.     moveq #0,d0
  100. df1idloop    lsl.l #1,d0
  101.     bclr d1,$100(a1)
  102.     btst #5,$1001(a1)
  103.     beq.s nxtbit
  104.     ori.w #1,d0
  105. nxtbit    bset d1,$100(a1)
  106.     dbf d7,df1idloop
  107.     not.l d0
  108.     cmpi.l #-1,d0        
  109.     bne.s no_drive        
  110.     bset d1,drives_avail(a2)
  111.  
  112. no_drive    addq.w #1,d1
  113.     cmpi.w #7,d1
  114.     bne.s ID_drives
  115.     bsr motor_off
  116.  
  117.     moveq #0,d0        ;now identify any disks present.
  118.     moveq #3,d1        
  119. id_dsk_lp    btst d1,drives_avail(a2)
  120.     beq.s no_drv
  121.     move.b d0,use_drive(a2)
  122.     move.b #$ff,$100(a1)
  123.     bclr d1,$100(a1)
  124.     bsr stepin
  125.     bsr initialize_drive
  126.     btst #2,$1001(a1)
  127.     beq.s no_drv
  128.     move.b #1,start_motor(a2)
  129.     bsr identify_disk
  130. no_drv    bsr motor_off
  131.     addq.w #1,d1
  132.     addq.w #1,d0
  133.     cmpi.w #4,d0
  134.     bne.s id_dsk_lp
  135.     movem.l (a7)+,a0-a6/d0-d7
  136.     rts
  137.  
  138. *****************************************************************************
  139.  
  140. ***************
  141. * File Loader *
  142. ***************
  143.  
  144. LOAD_FILE    movem.l d0-d6/a0-a4/a6,-(a7)
  145.     move.l #$bfd000,a1
  146.     move.l #Variables,a2
  147.     move.l a5,load_address(a2)
  148.     move.b d7,mode(a2)
  149.  
  150.     move.l a6,a0        ;analyse file name for path.
  151.     moveq #0,d0
  152. find_path    tst.b (a0)
  153.     beq no_path
  154.     cmpi.b #":",(a0)+
  155.     beq.s found_path
  156.     addq.w #1,d0
  157.     cmpi.w #32,d0
  158.     bne.s find_path
  159.     bra no_path
  160. found_path
  161.     moveq #0,d2        ;direct drive access (df0: etc?)
  162.     move.l #direct_names,a0
  163. lk_direct    moveq #4,d1
  164.     bsr compare_text
  165.     tst.w d7
  166.     bne.s direct_path
  167.     addq.w #4,a0
  168.     addq.w #1,d2
  169.     cmpi.w #4,d2
  170.     bne.s lk_direct        
  171.     bra not_direct
  172.  
  173. direct_path
  174.     
  175.     move.l d2,d1        ;direct drive access requested
  176.     addq #3,d1        ;but is that drive available?
  177.     btst d1,drives_avail(a2)
  178.     bne.s drv_avl
  179.     move.b #$0a,error(a2)    ;no - error $0a
  180.     bra load_end    
  181. drv_avl
  182.     cmp.b use_drive(a2),d2    ;same drive used previously?
  183.     beq Go_load
  184.     bsr motor_off
  185.     move.b d2,use_drive(a2)    ;select it if not
  186.     move.b #$ff,$100(a1)
  187.     bclr d1,$100(a1)
  188.     bsr wait1msec
  189.  
  190. same_drv1    btst #2,$1001(a1)        ;disk in?
  191.     beq Dchngd1
  192.     move.b #1,start_motor(a2)
  193.     bra Go_load
  194.     
  195. Dchngd1    bsr test_step
  196.     btst #2,$1001(a1)        ;disk in now?
  197.     bne.s Dnowin
  198.     move.b #$0b,error(a2)    ;no disk in that drive-error $0b
  199.     bra load_end    
  200.  
  201. Dnowin    move.b #1,start_motor(a2)
  202.     bsr initialize_drive
  203.     bsr identify_disk
  204.           bra Go_load
  205.  
  206. not_direct
  207.     
  208.     lea disk_names(a2),a0    ;look through currently inserted
  209.     addq.w #1,a0
  210.     moveq #0,d2                   ;disks for that diskname.
  211.  
  212. lk_disk    move.w d0,d1
  213.     cmp.b -$1(a0),d0        ;compare diskname length
  214.     bne.s not_in2
  215.     bsr compare_text
  216.     tst.w d7
  217.     bne.s got_path
  218.  
  219. not_in2    add.w #$20,a0        ;look in next drives name-store
  220.     addq.w #1,d2
  221.     cmpi.w #4,d2
  222.     bne.s lk_disk    
  223.     bra not_inserted
  224.  
  225. got_path    cmp.b use_drive(a2),d2    ;same drive used previously?
  226.     beq Go_load
  227.     bsr motor_off
  228.     move.b d2,use_drive(a2)    ;select it if not
  229.     move.b #$ff,$100(a1)
  230.     move.l d2,d1
  231.     addq.w #3,d1
  232.     bclr d1,$100(a1)
  233.     bsr wait1msec
  234.     btst #2,$1001(a1)        ;disk in?
  235.     beq Doutnow        
  236.     move.b #1,start_motor(a2)
  237.     bra Go_load
  238.  
  239. Doutnow    subq.w #1,a0        ;ejected - clear stored name
  240.     moveq #$1f,d7        
  241. clr_name    clr.b (a0)+
  242.     dbf d7,clr_name        
  243.  
  244. not_inserted
  245.  
  246.     moveq #0,d2        ;see if any disks have been
  247. tdrv_loop    move.w d2,d1        ;replaced, and identify any new
  248.     add.w #3,d1        ;disks. If any match req then
  249.     bsr motor_off        ;load.
  250.     btst d1,drives_avail(a2)
  251.     beq.s nxt_drv
  252.     move.b #$ff,$100(a1)
  253.     bclr d1,$100(a1)
  254.     bsr wait1msec
  255.     btst #2,$1001(a1)
  256.     bne.s nxt_drv
  257.     move.b d2,use_drive(a2)
  258.     bsr test_step
  259.     btst #2,$1001(a1)
  260.     bne.s dsk_now_in
  261.     lea disk_names(a2),a0    ;still no disk so wipe diskname
  262.     move.w d2,d1
  263.     lsl.w #5,d1
  264.     add.w d1,a0
  265.     moveq #$1f,d1
  266. wipe_dn    clr.b (a0)+
  267.     dbf d1,wipe_dn    
  268.     bra.s nxt_drv
  269. dsk_now_in
  270.     move.b #1,start_motor(a2)
  271.     bsr initialize_drive
  272.     bsr identify_disk
  273.     lea disk_names(a2),a0    ;correct diskname
  274.     move.w d2,d1
  275.     lsl.w #5,d1
  276.     add.w d1,a0
  277.     cmp.b (a0),d0        ;compare diskname length
  278.     bne.s nxt_drv
  279.     move.w d0,d1
  280.     addq.w #1,a0
  281.     bsr compare_text
  282.     tst.w d7        
  283.     bne Go_load
  284.  
  285. nxt_drv    addq.w #1,d2
  286.     cmpi.w #4,d2
  287.     bne.s tdrv_loop
  288.     move.b #$0c,error(a2)    ;disk not in any drive - error $c
  289.     bra Load_end
  290.  
  291. no_path    move.b #$0d,error(a2)    ;no path - error $d
  292.     bra Load_end
  293.  
  294. Go_load    lea $01(a6,d0.w),a6        ;bypass path part of filename
  295.     bsr Find_file
  296.  
  297. Load_end    move.b #$ff,track_in(a2)
  298.     tst.b error(a2)
  299.     beq.s no_error
  300.     bsr motor_off
  301.     move.w #1000,d7
  302.     bsr cia_wait
  303. no_error    moveq #0,d7
  304.     move.b error(a2),d7
  305.     movem.l (a7)+,d0-d6/a0-a4/a6
  306.     rts
  307.  
  308. ****************************************************************************
  309.  
  310. ********************
  311. * Shut down drives *
  312. ********************
  313.  
  314. MOTOR_OFF    movem.l a1/a2/d7,-(a7)
  315.     move.l #$bfd000,a1
  316.     move.l #Variables,a2
  317.     move.b #$ff,$100(a1)
  318.     move.b #$87,$100(a1)
  319.     bsr wait1msec
  320.     move.b #$ff,$100(a1)
  321.     move.b #$ff,use_drive(a2)
  322.     moveq #100,d7
  323.     bsr cia_wait
  324.     movem.l (a7)+,a1/a2/d7
  325.     rts
  326.  
  327. ****************************************************************************
  328.  
  329. *********************
  330. * Get Main Root Dir *
  331. *********************
  332.  
  333. Find_file    clr.b error(a2)
  334.     move.l #block_buffer,a0    ;get disk's root dir.
  335.     move.w #880,d0
  336.     bsr Get_block
  337.     tst.b error(a2)
  338.     bne file_eror
  339.  
  340. ******************************
  341. * Find File's Root Directory *
  342. ******************************
  343.  
  344. Find_files_root_dir_loop
  345.     
  346.     move.l a6,a4
  347.     moveq #0,d0    
  348.  
  349. dir_loop    move.b (a4),d7        ;find file's root dir
  350.     beq.s root_dir
  351.     cmpi.b #"/",d7        ;and get length of subdir name
  352.     beq.s oblique         ;if required.
  353.     addq.w #1,a4
  354.     addq.w #1,d0
  355.     bra dir_loop
  356.  
  357. oblique    move.w d0,d7        ;d0 = dir name length
  358.     move.w d0,d6        
  359.     subq.w #1,d7
  360.  
  361.     bsr hash_name        ;hash dir name into d0
  362.  
  363.     lsl.w #2,d0
  364.     move.l $18(a0,d0.w),d0    ;header block for this hash
  365.     beq file_not_found
  366.  
  367. get_dir_header
  368.  
  369.     bsr Get_block
  370.     tst.b error(a2)
  371.     bne file_eror
  372.  
  373.     bsr compare_names
  374.     tst.w d7
  375.     beq.s next_in_hash_chain
  376.     addq.w #1,a4
  377.     move.l a4,a6
  378.     bra find_files_root_dir_loop
  379.  
  380. next_in_hash_chain
  381.  
  382.     move.l $1f0(a0),d0
  383.     bne get_dir_header
  384.     bra file_not_found
  385.  
  386. **************************
  387. * Locate The File Itself *
  388. **************************
  389.  
  390. root_dir    move.w d0,d7        ;length of file name
  391.     move.w d0,d6
  392.     subq.w #1,d7
  393.  
  394.     bsr hash_name    
  395.  
  396.     lsl.w #2,d0
  397.     move.l $18(a0,d0.w),d0    ;header block number for this hash
  398.     beq file_not_found
  399.  
  400. get_header
  401.  
  402.     bsr Get_block
  403.     tst.b error(a2)
  404.     bne file_eror
  405.  
  406.     bsr compare_names
  407.     tst.w d7
  408.     bne.s correct_file_header
  409.  
  410.     move.l $1f0(a0),d0        ;any more in hash chain?
  411.     bne get_header
  412.     bra file_not_found
  413.  
  414. correct_file_header
  415.  
  416.     cmpi.l #-3,$1fc(a0)        ;make sure its a file header
  417.     beq.s file_header
  418.     move.b #8,error(a2)        ;not a file header-error 8
  419.     bra file_eror
  420.  
  421. file_header
  422.  
  423.     move.l load_address(a2),a5
  424.     move.l $144(a0),d6        ;length of file.
  425.     tst.b mode(a2)
  426.     beq.s transfer
  427.     move.l d6,a5
  428.     rts
  429. transfer
  430.     subq.l #1,d6    
  431.  
  432. transfer_loop
  433.  
  434.     move.l $10(a0),d0        ;next block location
  435.     beq file_not_found
  436.  
  437.     bsr Get_block
  438.     tst.b error(a2)
  439.     bne file_eror
  440.  
  441. ****************************************
  442. * Download data to file's load address *
  443. ****************************************
  444.  
  445.     lea $18(a0),a3        ;1st data longword in dos_block
  446.     moveq #$79,d7
  447. make_file    subq.l #4,d6
  448.     bmi.s last_bytes
  449.     move.l (a3)+,(a5)+    
  450.     dbf d7,make_file
  451.     bra transfer_loop
  452. last_bytes
  453.     addq.w #4,d6
  454. lb_loop    move.b (a3)+,(a5)+    
  455.     dbf d6,lb_loop
  456.     rts
  457.  
  458. file_not_found
  459.  
  460.     move.b #9,error(a2)        ;file not found-error 8
  461. file_eror    rts
  462.  
  463. *****************************
  464. * File Load Called Routines *
  465. *****************************
  466.  
  467. hash_name    move.l a6,a3
  468. hash_loop    moveq #0,d2        ;hash file name at a6
  469.     move.b (a3)+,d2        ;length-1 in d7.
  470.     cmpi.b #$60,d2
  471.     bls.s capital
  472.     cmpi.b #$7a,d2
  473.     bhi.s capital
  474.     subi.b #$20,d2
  475. capital    mulu #13,d0
  476.     add.l d2,d0
  477.     andi.l #$7ff,d0
  478.     dbf d7,hash_loop
  479.     divu #72,d0
  480.     swap d0            ;d0=hash number
  481.     rts
  482.  
  483. compare_names
  484.  
  485.     moveq #0,d7
  486.     cmp.b $1b0(a0),d6        ;d6=length of name being tested
  487.     bne.s name_fail
  488.     move.w d6,d5
  489.     move.l a6,a3
  490.     lea $1b1(a0),a5
  491.     subq.w #1,d5    
  492. comp_loop    move.b (a3)+,d1        ;Case desensitize filename
  493.     move.b (a5)+,d2        ;compare.
  494.     andi.b #$df,d1
  495.     andi.b #$df,d2
  496.     cmp.b d1,d2
  497.     dbne d5,comp_loop
  498.     tst.w d5
  499.     bpl.s name_fail
  500.     moveq #1,d7
  501. name_fail    rts
  502.  
  503. compare_text
  504.     
  505.     movem.l a0/a6/d2/d3,-(a7)    ;Text comparison.
  506.     subq.w #1,d1
  507.     moveq #0,d7        ;d1 = number of chars to compare
  508. cmp_loop2    move.b (a0)+,d2        ;Strings at A0 and A6
  509.     move.b (a6)+,d3        ;d7: 0 = different, 1 = same.
  510.     andi.b #$df,d2
  511.     andi.b #$df,d3
  512.     cmp.b d2,d3
  513.     bne not_same
  514.     dbf d1,cmp_loop2
  515. txt_same    moveq #1,d7
  516. not_same    movem.l (a7)+,a0/a6/d2/d3
  517.     rts
  518.  
  519. *****************************************************************************
  520.  
  521. *********************************
  522. * Get a disk block into buffer! *
  523. *********************************
  524.  
  525. * D0 will equal block number required ($0 - $6df)
  526.  
  527. Get_block    movem.l a0-a6/d0-d7,-(a7)
  528.     move.w #$0504,attempts(a2)
  529.     andi.l #$ffff,d0
  530.     cmpi.w #$6df,d0        ;check range
  531.     bls blk_in_range
  532.     move.b #7,error(a2)
  533.     bra no_reload
  534.  
  535. blk_in_range
  536.  
  537.     move.l d0,d1
  538.     divu #11,d1        ;what cylinder is that on?
  539.     cmp.b track_in(a2),d1
  540.     beq.s Trksde_in        ;that track is already in.
  541.  
  542. Reload    bsr Fetch_trackside        ;loads track required
  543.     tst.b error(a2)
  544.     bne No_reload
  545.  
  546. Trksde_in    clr.b error(a2)
  547.     move.l #MFMbuffer,a3
  548.     lea $31fe(a3),a0
  549. find_sync    move.w #$4489,d7
  550. fs_loop    cmp.w (a3)+,d7
  551.     beq found_sync
  552.     cmp.l a0,a3
  553.     bls.s fs_loop
  554.     move.b #4,error(a2)        ;couldnt find that sector-error 4
  555.     bra MFM_error
  556.  
  557. found_sync    
  558.  
  559.     cmp.w (a3),d7
  560.     beq.s syncstart
  561.     subq.w #2,a3
  562.  
  563. syncstart    lea $2a(a3),a4        ;Check header checksum.
  564.     bsr decode_lw        
  565.     move.l $2(a3),d3
  566.     move.l $6(a3),d4
  567.     andi.l #$55555555,d3
  568.     andi.l #$55555555,d4
  569.     eor.l d4,d3
  570.     cmp.l d3,d5
  571.     bne Not_sector
  572.  
  573.     lea $2(a3),a4        ;Track mark = Head position?
  574.     bsr decode_lw
  575.     move.l d5,d4        
  576.     swap d4
  577.     moveq #0,d7
  578.     move.b use_drive(a2),d7
  579.     cmp.b tracksides(a2,d7.w),d4
  580.     beq Track_mark_ok
  581.     move.b #5,error(a2)        ;wrong track mark - error 5
  582.     bra MFM_error
  583.  
  584. Track_mark_ok
  585.  
  586.     lsr.w #8,d5        ;Is this the sector required?
  587.     move.l d1,d7
  588.     swap d7
  589.     cmp.b d5,d7
  590.     beq.s Found_block
  591.     
  592. Not_sector
  593.  
  594.     add.w #$430,a3          ;loop until find correct sector
  595.     bra find_sync
  596.  
  597. Found_Block
  598.  
  599.     moveq #0,d2        ;Put converted mfm at dest addr.
  600.     move.l #$55555555,d7
  601.     move.l #block_buffer,a6
  602.     lea $3a(a3),a4        
  603.     lea $23a(a3),a5
  604.     moveq #$7f,d3
  605.     
  606. next_lw    move.l (a4)+,d6
  607.     move.l (a5)+,d5
  608.     and.l d7,d6
  609.     and.l d7,d5
  610.     eor.l d6,d2        ;update checksum
  611.     eor.l d5,d2
  612.     add.l d6,d6
  613.     or.l d5,d6
  614.     move.l d6,(a6)+
  615.     dbf d3,next_lw
  616.     
  617.     sub.w #$208,a4
  618.     bsr decode_lw
  619.     cmp.l d5,d2
  620.     beq.s no_reload
  621.     move.b #6,error(a2)        ;checksum error - error 6
  622.     
  623. MFM_error    subq.b #1,attempts(a2)
  624.     bne Reload
  625.     bsr initialize_drive
  626.     move.b #5,attempts(a2)
  627.     subq.b #1,attempts+1(a2)
  628.     bne Reload
  629.     
  630. No_reload    movem.l (a7)+,a0-a6/d0-d7
  631.     rts
  632.  
  633. *****************************************************************************
  634.  
  635. *********************
  636. * MFM Track loader! *
  637. *********************
  638.  
  639. * D1 will equal trackside 0 - 159
  640.  
  641. Fetch_trackside
  642.     
  643.     movem.l a0/d0-d3,-(a7)    
  644.     move.l #$dff000,a0
  645.     clr.b error(a2)        
  646.     tst.b start_motor(a2)    ;motor on already?
  647.     beq.s motor_ok
  648.  
  649.     clr.b start_motor(a2)
  650.     move.b #$7f,$100(a1)
  651.     moveq #3,d7
  652.     add.b use_drive(a2),d7
  653.     bclr d7,$100(a1)
  654.     move.w #200,d2        ;wait for correct motor speed.
  655. wdskrdy    moveq #10,d7
  656.     bsr cia_wait        
  657.     btst #5,$1001(a1)        
  658.     dbeq d2,wdskrdy
  659.     tst.w d2
  660.     bpl.s motor_ok
  661.     move.b #1,error(a2)        ;no speed signal - error 1
  662.     btst #2,$1001(a1)                
  663.     bne.s disk_ok
  664.     move.b #3,error(a2)        ;disk removed - error 3
  665. disk_ok    bra trackload_end
  666.  
  667. motor_ok    move.w d1,d3
  668.     lsr.b #1,d3        ;select disk side to load from.
  669.     bcc.s head1
  670.     bclr #2,$100(a1)
  671.     bra.s checkhead
  672. head1    bset #2,$100(a1)
  673.  
  674. checkhead    moveq #0,d7
  675.     move.b use_drive(a2),d7
  676.     move.b tracksides(a2,d7.w),d2    ;ensure head is over correct
  677.     lsr.b #1,d2        ;track
  678.     cmp.b d2,d3
  679.     beq.s headok
  680.     bls.s seekout
  681.     bsr stepin
  682.     bra.s checkhead 
  683. seekout    bsr stepout    
  684.     bra.s checkhead
  685.  
  686. headok    moveq #0,d7
  687.     move.b use_drive(a2),d7
  688.     move.b d1,tracksides(a2,d7.w)
  689.     move.w #$2,$9c(a0)        ;clear disk block irq
  690.     moveq #18,d7        ;settle wait.
  691.     bsr cia_wait
  692.  
  693.     move.l #mfmbuffer,$20(a0)
  694.     move.w #$4000,$24(a0)    
  695.     move.w #$8010,$96(a0)    ;enable dma
  696.     move.w #$6800,$9e(a0)    
  697.     move.w #$9500,$9e(a0)
  698.     move.w #$4489,$7e(a0)    ;sync
  699.     move.w #$9900,$24(a0)    
  700.     move.w #$9900,$24(a0)    
  701.  
  702.     move.w #200,d2
  703. waitdirq    moveq #10,d7
  704.     bsr cia_wait        
  705.     btst #1,$1f(a0)        
  706.     dbne d2,waitdirq
  707.     tst.w d2
  708.     bpl.s read_ok
  709.     move.b #2,error(a2)        ;No DMA finish-Time Out-error 2
  710.  
  711. read_ok    move.b d1,track_in(a2)
  712.     move.w #$4000,$24(a0)    
  713.     move.w #$10,$96(a0)        ;disable dma
  714.  
  715. Trackload_end
  716.  
  717.     movem.l (a7)+,a0/d0-d3
  718.     rts
  719.  
  720. *******************************************************************************
  721.  
  722. ******************************
  723. * MFM + disk h/ware routines *
  724. ******************************
  725.  
  726. decode_lw    move.l #$55555555,d7    ;decode two consec mfm longwords
  727.     move.l (a4),d5        ;into d5
  728.     move.l $4(a4),d4    
  729.     and.l d7,d5    
  730.     and.l d7,d4
  731.     add.l d5,d5
  732.     or.l d4,d5        
  733.     rts
  734.  
  735. stepout    moveq #0,d7
  736.     move.b use_drive(a2),d7
  737.     subq.b #2,tracksides(a2,d7.w)
  738.     bset #1,$100(a1)
  739.     bra.s step
  740.  
  741. stepin    moveq #0,d7
  742.     move.b use_drive(a2),d7
  743.     addq.b #2,tracksides(a2,d7.w)
  744.     bclr #1,$100(a1)
  745. step    bsr.s shortwait
  746.     bclr #0,$100(a1)
  747.     bsr.s shortwait
  748.     bset #0,$100(a1)
  749.     moveq #4,d7
  750.     bsr cia_wait
  751.     rts
  752. shortwait
  753.     nop
  754.     nop
  755.     nop
  756.     nop
  757.     rts
  758.  
  759. initialize_drive
  760.  
  761.     btst #$4,$1001(a1)        
  762.     beq.s gottrack0
  763.     bsr.s stepout
  764.     bra.s initialize_drive
  765.  
  766. gottrack0    moveq #0,d7
  767.     move.b use_drive(a2),d7
  768.     clr.b tracksides(a2,d7.w)    
  769.     move.w #20,d7
  770.     bsr cia_wait
  771.     rts
  772.  
  773. Identify_disk
  774.  
  775.     movem.l a5/a6/d0-d1/d4-d7,-(a7)
  776.     move.w #$370,d0
  777.     bsr get_block
  778.     moveq #0,d6
  779.     move.b use_drive(a2),d6
  780.     lea disk_names(a2),a5
  781.     lsl.w #5,d6
  782.     add.w d6,a5
  783.     tst.b error(a2)
  784.     beq.s dirblk_ok
  785.     moveq #$1f,d7        ;disk bad - clear name
  786. clr_name2    clr.b (a5)+
  787.     dbf d7,clr_name2
  788.     bra identifd
  789.  
  790. dirblk_ok    move.l #block_buffer+$1b0,a6    ;copy name to store
  791.     moveq #0,d7
  792.     move.b (a6),d7
  793. copy_name    move.b (a6)+,(a5)+
  794.     dbf d7,copy_name        
  795.  
  796. Identifd    move.b #$ff,track_in(a2)
  797.     movem.l (a7)+,a5/a6/d0-d1/d4-d7
  798.     rts
  799.  
  800. test_step    moveq #0,d7
  801.     move.b use_drive(a2),d7
  802.     btst #1,tracksides(a2,d7.w)
  803.     beq.s chkstp_in
  804.     bsr stepout
  805.     bra stepdone
  806. chkstp_in    bsr stepin        
  807. stepdone    rts
  808.  
  809.  
  810. wait1msec    moveq #1,d7
  811.  
  812. cia_wait    move.b #$08,$f00(a1)    ;set one shot / stop timer
  813.     move.b #$cc,$600(a1)    ;set timer lo
  814.     move.b #$02,$700(a1)    ;set timer hi (starts counter)
  815. ciawlp2    btst #0,$f00(a1)        ;wait for ciab timer b to timeout
  816.     bne.s ciawlp2
  817.     subq.w #1,d7
  818.     bne.s cia_wait        ;d1 = milliseconds to wait.
  819.     rts
  820.  
  821. *******************************************************************************
  822.  
  823. attempts     equ $0
  824. error           equ $2
  825. start_motor  equ $3
  826. tracksides   equ $4
  827. track_in     equ $8
  828. use_drive    equ $9
  829. drives_avail equ $a
  830. mode         equ $b
  831. load_address equ $c
  832. disk_names   equ $10
  833.  
  834. variables    dcb.l $24,$0
  835.  
  836. direct_names
  837.  
  838.     dc.b "df0:df1:df2:df3:"
  839.     
  840. block_buffer    
  841.  
  842.     dcb.w $100,$0000
  843.  
  844.  
  845.     section chipstuff,data_c
  846.  
  847. mfmbuffer    dcb.w $1910,$0000
  848.  
  849. *******************************************************************************
  850.  
  851.